package CompareScheme;

import accessstruct.Tool;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;

/**
 * @Classname psper4
 * @Description
[1]X. Li, H. Quan, C.-C. Chang, T. Baker, and H. Tian,
“A Lightweight Attribute-Based Access Control Scheme for Intelligent Transportation System With Full Privacy Protection”.
 * @Created by kevin
 */
public class paper4 {
    public static long CASetup(int attNum){

        Pairing bp = PairingFactory.getPairing("a.properties");//
        long start = System.currentTimeMillis();
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element h = bp.getG1().newRandomElement().getImmutable();//
        Element u = bp.getG1().newRandomElement().getImmutable();//
        Element Y= bp.pairing(g,h).getImmutable();
        long end = System.currentTimeMillis();
        return end-start;
    }
    public static long AASetup(int attNum){

        Pairing bp = PairingFactory.getPairing("a.properties");//
        long start = System.currentTimeMillis();
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element alpha = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element eggalpha= bp.pairing(g,g).powZn(alpha).getImmutable();
        Element h= bp.getZr().newRandomElement().getImmutable();//
        Element hbeta= h.powZn(beta).getImmutable();//
        long end = System.currentTimeMillis();
        return end-start;
    }
    public static long KeyGen(int attNum) throws Exception{
        Pairing bp = PairingFactory.getPairing("a.properties");//
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element u = bp.getG1().newRandomElement().getImmutable();//
        Element alpha = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element eggalpha= bp.pairing(g,g).powZn(alpha).getImmutable();
        Element h= bp.getG1().newRandomElement().getImmutable();//
        Element hbeta= h.powZn(beta).getImmutable();//
        Element Y= bp.pairing(g,h).getImmutable();
        long start = System.currentTimeMillis();
        Element k1 = bp.getZr().newRandomElement().getImmutable();//
        Element k2 = bp.getZr().newRandomElement().getImmutable();//
        Element cu = bp.getZr().newRandomElement().getImmutable();//
        Element eu = bp.getZr().newRandomElement().getImmutable();//
        Element mu = bp.getZr().newRandomElement().getImmutable();//
        Element Ki0_ = h.powZn(mu).powZn(k1).getImmutable();
        Element Ki0 = Ki0_.powZn(beta.mul(cu)).mul(g.powZn(alpha)).getImmutable();
        Element Ki1_ = g.powZn(k1).getImmutable();
        Element Ki1 = Ki1_.powZn(beta.mul(cu)).getImmutable();
        Element Ki3_ = g.powZn(k2.mul(k1.invert())).getImmutable();
        Element Ki3 = Ki3_.powZn(eu.mul(cu.invert())).getImmutable();

        for(int i = 0 ;i<attNum;i++){
            byte[] attHash1 = Tool.sha1(Integer.toString(attNum));
            Element si = bp.getZr().newElementFromHash(attHash1, 0, attHash1.length).getImmutable();
            Element kij2_ = u.powZn(si).mul(hbeta).powZn(k2.mul(k1.invert())).getImmutable();
            Element kij2 = kij2_.powZn(eu.mul(cu.invert())).getImmutable();
        }
        long end = System.currentTimeMillis();
        return end-start;
    }

    public static long Encrypt(int attNum)throws Exception{

        Pairing bp = PairingFactory.getPairing("a.properties");//
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element u = bp.getG1().newRandomElement().getImmutable();//
        Element alpha = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element eggalpha= bp.pairing(g,g).powZn(alpha).getImmutable();
        Element h= bp.getG1().newRandomElement().getImmutable();//
        Element hbeta= h.powZn(beta).getImmutable();//
        Element Y= bp.pairing(g,h).getImmutable();
        //离线
        Element s= bp.getZr().newRandomElement().getImmutable();//
        Element key = eggalpha.powZn(s).getImmutable();
        Element message = bp.getGT().newZeroElement().getImmutable();//
        Element C0 =g.powZn(s).getImmutable();
        for(int i = 0 ;i<attNum;i++ ){
            Element xj = bp.getZr().newRandomElement().getImmutable();//
            Element tj = bp.getZr().newRandomElement().getImmutable();//
            Element lambdax = bp.getZr().newRandomElement().getImmutable();//
            Element omegax = bp.getZr().newRandomElement().getImmutable();//
            byte[] attHash1 = Tool.sha1(Integer.toString(attNum));
            Element hx = bp.getG1().newElementFromHash(attHash1, 0, attHash1.length).getImmutable();
            Element Cj1 = g.powZn(tj.invert()).getImmutable();
            Element Cj2 = u.powZn(xj).mul(hbeta).powZn(tj).getImmutable();
            Element Cj3 = h.powZn(xj).getImmutable();
        }
        long start = System.currentTimeMillis();
        Element tj = bp.getZr().newRandomElement().getImmutable();//
        Element xj = bp.getZr().newRandomElement().getImmutable();//
        for(int i = 0 ;i<attNum;i++ ){
            byte[] attHash1 = Tool.sha1(Integer.toString(attNum));
            Element rhoj = bp.getZr().newElementFromHash(attHash1, 0, attHash1.length).getImmutable();
            Element lambdaj = bp.getZr().newRandomElement().getImmutable();//
            Element cj4 = lambdaj.sub(xj).getImmutable();
            Element cj5 = tj.mul(rhoj.sub(xj)).getImmutable();
        }
        long end = System.currentTimeMillis();
        return end-start;
    }
    public static long Decrypt(int attNum)throws Exception {
        Pairing bp = PairingFactory.getPairing("a.properties");//

        String gid= "1024";
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element h = bp.getG1().newRandomElement().getImmutable();//
        Element message = bp.getGT().newZeroElement().getImmutable();//
        Element  s = bp.getZr().newRandomElement().getImmutable();//
        Element  t = bp.getZr().newRandomElement().getImmutable();//
        Element  mu = bp.getZr().newRandomElement().getImmutable();//
        Element  alpha = bp.getZr().newRandomElement().getImmutable();//
        Element  beta = bp.getZr().newRandomElement().getImmutable();//
        Element  fu = bp.getZr().newRandomElement().getImmutable();//
        Element C0 =message.mul(bp.pairing(g,g).powZn(alpha.mul(s).mul(t.invert()))).mul(bp.pairing(g,h).powZn(mu.mul(beta).mul(fu).mul(s).mul(t.invert()))).getImmutable();
        Element Ctgid =message.mul(bp.pairing(g,h).powZn(mu.mul(beta).mul(fu).mul(s).mul(t.invert()))).getImmutable();
        long start = System.currentTimeMillis();

        Element m = C0.div(Ctgid).powZn(t).getImmutable();
        long end = System.currentTimeMillis();
        return end-start;
    }
}
